#include "common/pch.h"
#include "metadata/areatrigger_teleport.h"

#include <cftf/loger/syslog.h>
#include <cftc/reflect/class.h>
#include <cftc/reflect/field.h>

#include "dbc/structure.h"

namespace mt
{

	CFT_IMPLEMENT_REFLECT_CLASS_BEGIN(AreaTrigger, cftc::reflect::Object);
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(id, R"(wow_meta:"field_name:id")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(condition, R"(wow_meta:"field_name:condition_id")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(target_mapId, R"(wow_meta:"field_name:target_map")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(target_X, R"(wow_meta:"field_name:target_position_x")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(target_Y, R"(wow_meta:"field_name:target_position_y")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(target_Z, R"(wow_meta:"field_name:target_position_z")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(target_Orientation, R"(wow_meta:"field_name:target_orientation")");
        CFT_IMPLEMENT_REFLECT_FIELD_ANNOTATION(failed_text_mangos_string_id, R"(wow_meta:"field_name:status_failed_mangos_string_id")");
	CFT_IMPLEMENT_REFLECT_CLASS_END();

	bool AreaTrigger::IsLessOrEqualThan(AreaTrigger const* l) const
	{
        CFT_ASSERT(target_mapId == l->target_mapId);
        if (!condition)
        {
            return true;
        }

        if (!l->condition)
        {
            return false;
        }

        if (condition == l->condition)
        {
            return true;
        }

#if 0
        // most conditions for AT have level requirement
        // let's order by the least restrictive
        const PlayerCondition* pCond1 = sConditionStorage.LookupEntry<PlayerCondition>(condition);
        const PlayerCondition* pCond2 = sConditionStorage.LookupEntry<PlayerCondition>(l->condition);
        if (pCond1->m_condition == CONDITION_LEVEL && pCond2->m_condition == CONDITION_LEVEL)
        {
            return (pCond1->m_value1 <= pCond2->m_value1);
        }
        if (pCond1->m_condition == CONDITION_LEVEL)
        {
            return false;
        }
        if (pCond2->m_condition == CONDITION_LEVEL)
        {
            return true;
        }
#endif
        return false;
	}

    const AreaTrigger* AreaTrigger::GetMapEntranceTrigger(unsigned int map_id)
    {
        auto map_dbc = dbc::MapEntry::GetElement(map_id);
        if (!map_dbc) {
            return nullptr;
        }
        const AreaTrigger* result = nullptr;
        AreaTrigger::Traverse(
            [map_id, map_dbc, &result](const AreaTrigger* meta, bool& stop)
            {
                if (meta->target_mapId == map_id) {
                    if (map_dbc->Instanceable()) {
                        if (result || result->IsLessOrEqualThan(meta)) {
                            result = meta;
                        }
                    } else {
                        if (!result || meta->IsLessOrEqualThan(result)) {
                            if (meta->IsMinimal()) {
                                result = meta;
                                stop = true;
                                return;
                            }

                            result = meta;
                        }
                    }
                }
            }
        );
        return result;
    }

    const AreaTrigger* AreaTrigger::GetGoBackTrigger(unsigned int map_id)
    {
#if 1
        return nullptr;
#endif
    }

}